
#include "World/World.h"
#include "SDL_collide.h"

//included for changing log file name
#include <stdio.h>

#include "ChangeDetection/include/ChangeDetectionAgentObserver.h"
#include "ChangeDetection/include/ChangeDetectionSharedData.h"

#include <iostream>
#include <boost/filesystem.hpp> //DISABLE FOR RUNNING ON LISA, HOWEVER CAN BE VERY USEFUL!!

ChangeDetectionAgentObserver::ChangeDetectionAgentObserver( )
{
}

ChangeDetectionAgentObserver::ChangeDetectionAgentObserver( RobotAgentWorldModel *__wm )
{
	this->_wm = (ChangeDetectionAgentWorldModel*)__wm;
	maxLoggedBlock = -1;
}

ChangeDetectionAgentObserver::~ChangeDetectionAgentObserver()
{
	// nothing to do.
}

void ChangeDetectionAgentObserver::reset()
{
	// nothing to do.
}

void ChangeDetectionAgentObserver::step()
{
	RobotAgentPtr agent = gWorld->getAgent(_wm->_agentId);
	// nothing to do.
	if (gWorld->getIterations() % gOrganismSampleFrequency == 0) {
		ChangeDetectionSharedData::locationLogFile << _wm->_agentId << "," << gWorld->getIterations();
		
		int orgSize = 1;
		int orgId = 0;
		if(agent->isPartOfOrganism()){
			orgSize = agent->getOrganism()->size();
			orgId = agent->getOrganism()->getId();
		}
		ChangeDetectionSharedData::locationLogFile << "," << _wm->getPosition().x << "," << _wm->getPosition().y << "," << agent->isPartOfOrganism() << "," << orgSize << "," << orgId << "," << _wm->swarmTime << "," << _wm->organismTime << std::endl;
	}

	int currentXCoordinate = _wm->getPosition().x;
	int currentBlock = currentXCoordinate/xCoordinatesBeforeLog;

	if(_wm->wrapAround==true){
		//wrapCount++;
		maxLoggedBlock=-1; //if wraparound happened, you have to continue logging, so reset the maxLoggedBlock
		_wm->wrapAround=false; //reset here (and not in the controller) to make sure the observer detects the wraparound
	}

	if(currentBlock>maxLoggedBlock){
		maxLoggedBlock=currentBlock;
		ChangeDetectionSharedData::clusterLogLogFile << _wm->_agentId << "," << gWorld->getIterations() << ","
				<< _wm->getPosition().x << "," << _wm->getPosition().y << "," << _wm->wrapCount << "," <<currentBlock <<","
				<< _wm->currentCluster <<"," << _wm->clusterCount << std::endl;
	}

	//DISABLE BELOW FOR RUNNING ON LISA, HOWEVER CAN BE VERY USEFUL!!
	if(ChangeDetectionSharedData::evolutionMode == "basicchangedetection"){
		if(gWorld->getIterations()==gMaxIt-1){
			std::string newname = ChangeDetectionSharedData::gClusterLogLogFilename;
			newname = newname.substr(0, newname.size()-4);
			std::stringstream newNameCreator;
			newNameCreator << newname << "_" << _wm->statisticalProb << "," << _wm->historySize << "," << _wm->sensorCount << ".log";
			newname = newNameCreator.str();

			boost::filesystem::rename(ChangeDetectionSharedData::gClusterLogLogFilename.c_str(),newname);
		}
	}


	if(gWorld->getIterations()%20==0){
		ChangeDetectionSharedData::travelTrackingFile << _wm->_agentId << "," << gWorld->getIterations() << ","
			<< _wm->getPosition().x << "," << _wm->getPosition().y << "," << _wm->CManager.getClusterCount() << "," << _wm->wrapCount << "," <<currentBlock <<","
			<< _wm->distanceTraveled << ","<< _wm->distanceTraveledLastIteration << std::endl;
	}


	//only print for agent 0, otherwise every agent will print the same thing
	if(_wm->_agentId == 0 && gWorld->getIterations()==gMaxIt-1){
		std::cout << "I'm done!";
	}

	//only print for agent 0, otherwise every agent will print the same thing
	if(_wm->_agentId == 0 &&gWorld->getIterations()%1000==0){
		double perc = (double)gWorld->getIterations()/(double)gMaxIt*100;
		std::cout << "Percentage done: " << perc << "%" << std::endl;
	}
}
